/*
 * Created on Oct 13, 2006
 */
package com.mgmaps.gps;

import java.io.*;

import javax.microedition.io.*;
import com.mgmaps.app.APPSettings;
import com.mgmaps.utils.ExtLogger;

/**
 * Receiver for GPS information as NMEA statements over a serial port.
 *
 * @author CristiS
 * @version 1.0
 */
public class GPSSerial extends GPSNMEA {

  // have we printed a connect error message?
  private boolean msgPrinted;
  private DataOutputStream os;
  
  // for Sony-Ericsson HGE-100
  private final static byte[] SE_STA = { '$', 'S', 'T', 'A', 13, 10 };
  private final static byte[] SE_STO = { '$', 'S', 'T', 'O', 13, 10 };
  
  private boolean attempted;
  
  /**
   * Constructor for GPSSerial.
   */
  public GPSSerial() {
    super();
    msgPrinted = false;
    
    // don't auto-start
    // start();
  }
  
  /**
   * Connect to a serial URL.
   * 
   * @return true if the connection was established
   */
  public synchronized boolean connect() {
    try {
      if (APPSettings.gpsDevice.length() == 0 || !APPSettings.gpsDevice.startsWith("comm:"))
        return false;
      try {
        String gpsDev = APPSettings.gpsDevice;
        if (gpsDev.indexOf(';') < 0)
          gpsDev += ";baudrate=4800";
        connection = Connector.open(gpsDev);
      }
      catch (ConnectionNotFoundException cnf) {
        ExtLogger.handle(cnf, false, "Error connecting to " + APPSettings.gpsDevice);
        connection = Connector.open("nokia" + APPSettings.gpsDevice);
      }
      is = ((StreamConnection) connection).openDataInputStream();
      connected = true;
      ExtLogger.debug("(Re-)connected to GPS");
      
      // Sony-Ericsson needs $STA/$STO
      os = null;
      if (APPSettings.gpsDevice.startsWith("comm:at") || APPSettings.gpsDevice.startsWith("comm:AT")) {
        os = ((StreamConnection) connection).openDataOutputStream();
        os.write(SE_STA);
        os.flush();
        ExtLogger.debug("Sent start command");
      }
    }
    catch (Exception ex) {
      if (!msgPrinted) {
        msgPrinted = true;
        ExtLogger.handle(ex, false, "Error connecting to GPS");
      }
      disconnect(false);
    }
    
    attempted = true;

    return connected;
  }
  
  public boolean connectError() {
    return attempted && !connected;
  }
  
  /**
   * Disconnect.
   * 
   * @param notifyFlag whether to notify
   */
  public synchronized void disconnect(boolean notifyFlag) {
    try {
      if (os != null) {
        os.write(SE_STO);
        os.flush();
        ExtLogger.debug("Sent stop command");
        os.close();
      }
      if (is != null)
        is.close();
      if (connection != null)
        connection.close();
    }
    catch (IOException e) {
      ExtLogger.handle(e, false, "Error closing connection");
    }
    is = null;
    connection = null;
    connected = false;
    
    if (notifyFlag)
      notify();
  }
}
